using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using FireStarter.CodeGeneration;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration
{
    [TestFixture]
    public class TestLogicProjectGenerator: TestProjectGeneratorBase
    {
        private static LogicProjectGenerator CreateLogicProjectReadyToGenerate()
        {
            LogicProjectGenerator projectGenerator = new LogicProjectGenerator();
            CreateSolutionGenerator(projectGenerator);
            projectGenerator.ProjectPath = GetRootedPath(Path.Combine(TEST_PROJECTS_FOLDER, GetRandomString()));
            projectGenerator.ProjectName = "TestProject.Logic";
            projectGenerator.ModelSolution.BOProjectName = TestUtilsCodeGen.GetRandomString();
            return projectGenerator;
        }
        protected override IProjectGenerator CreateProjectReadyToGenerate()
        {
            return CreateLogicProjectReadyToGenerate();
        }

        protected override IProjectGenerator CreateProjectGenerator()
        {
            return new LogicProjectGenerator();
        }

        private void AssertProjectGeneratedCorrectly(LogicProjectGenerator logicProjectGenerator, ProjectFileManager boProjectFileManager)
        {
            string libFolderName = logicProjectGenerator.SolutionGenerator.HabaneroReferencePath;
            libFolderName = Utilities.GetRelativePath(libFolderName, logicProjectGenerator.ProjectPath);
            string projectFileName = logicProjectGenerator.ProjectFileName;
            Assert.IsTrue(Directory.Exists(logicProjectGenerator.ProjectPath));
            Assert.IsTrue(File.Exists(projectFileName));
            ProjectFileManager projectFileManager = new ProjectFileManager(projectFileName, CodeTemplateEnum.CSharpVisualStudio2005);
            Assert.AreEqual(OutputType.Library, projectFileManager.OutputType);
            string projectFileContents = File.ReadAllText(projectFileName);
            StringAssert.Contains(@"<Compile Include=""Properties\AssemblyInfo.cs"" />", projectFileContents);
            AssertHasProjectReference(projectFileContents, logicProjectGenerator, boProjectFileManager);
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Base.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.BO.dll", libFolderName));
            AssertHasNotReference(projectFileContents, string.Format(@"{0}\Habanero.Util.dll", libFolderName));
        }

        [Test]
        public void TestCreateLogicProjectGenerator()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IProjectGenerator projectGenerator = CreateProjectGenerator();
            //---------------Test Result -----------------------
            Assert.IsNotNull(projectGenerator);
            Assert.IsInstanceOf(typeof(LogicProjectGenerator), projectGenerator);
        }

        [Test]
        public void TestBoProjectReference()
        {
            //---------------Set up test pack-------------------
            string boProjectName = GetRandomString();
            LogicProjectGenerator projectGenerator = new LogicProjectGenerator();
            projectGenerator.SolutionGenerator = new SolutionGenerator();
            projectGenerator.SolutionGenerator.ModelSolution = new DMSolution();
            //---------------Assert Precondition----------------
            Assert.IsNull(projectGenerator.ModelSolution.BOProjectName);
            //---------------Execute Test ----------------------
            projectGenerator.ModelSolution.BOProjectName = boProjectName;
            //---------------Test Result -----------------------
            Assert.AreEqual(boProjectName, projectGenerator.ModelSolution.BOProjectName);
        }

        [Test]
        public void TestGenerate_Fails_BoProjectReferenceNotSet()
        {
            //---------------Set up test pack-------------------
            LogicProjectGenerator projectGenerator = CreateLogicProjectReadyToGenerate();
            projectGenerator.ModelSolution.BOProjectName = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(projectGenerator.ModelSolution.BOProjectName);
            //---------------Execute Test ----------------------
            Exception exception = null;
            try
            {
                projectGenerator.Generate();
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            //---------------Test Result -----------------------
            Assert.IsNotNull(exception, "Exception Expected");
            Assert.IsInstanceOf(typeof(ReferenceMissingException), exception);
            ReferenceMissingException referenceMissingException = (ReferenceMissingException)exception;
            Assert.AreEqual("BOProjectName", referenceMissingException.ReferenceName);
        }

        [Test]
        public void TestGenerate_Creates_ProjectFile_IfDoesNotExist()
        {
            //---------------Set up test pack-------------------
            LogicProjectGenerator projectGenerator = CreateLogicProjectReadyToGenerate();

            ProjectFileManager boProjectFileManager = CreateRandomProjectFile(projectGenerator.ModelSolution.BOProjectName);
            //---------------Assert Precondition----------------
            Assert.IsFalse(File.Exists(projectGenerator.ProjectFileName));
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            AssertProjectGeneratedCorrectly(projectGenerator, boProjectFileManager);
        }

        //public abstract class TestLogicProjectGenerator_GeneratedFile : TestProjectGeneratorBase_GeneratedFile
        //{
        //    protected override IProjectGenerator CreateProjectReadyToGenerate()
        //    {
        //        return CreateLogicProjectReadyToGenerate();
        //    }
        //}

        //public class TestLogicProjectGenerator_GeneratedFile_??? : TestLogicProjectGenerator_GeneratedFile
        //{
        //    protected override string GetFileName()
        //    {
        //        return "???";
        //    }
        //}
    }
}
